import { _decorator, Color, Component, Node, Sprite } from 'cc';
import { EBuff, EEvent, EntityType, EPlayerType } from './Config/Enum';
import { PlayerManager } from './PlayerManager';
import { EnemyManager } from './EnemyManager';
import { WallManager } from './WallManager';
import { Core } from './Core/Core';

const { ccclass, property } = _decorator;

export class Buff {
    id: number;
    type: EBuff;
    playerType: EPlayerType;
    duration: number;
    elapsed: number = 0;
    ap: number;
    color: Color;
    isDot: boolean = false;
    isPercentage:boolean = false;
    constructor(
        id: number, 
        type: EBuff, 
        playerType: EPlayerType,
        duration: number, 
        ap: number, 
        color: Color,
        isDot: boolean = false,
        isPercentage:boolean =false
    ) {
        this.id = id;
        this.type = type;
        this.playerType = playerType;
        this.duration = duration;
        this.ap = ap;
        this.color = color;
        this.isDot = isDot;
        this.isPercentage = isPercentage
    }
}

export class BuffManager {
    buffs: Buff[] = [];

    clearAllBuffs() {
        this.buffs = [];
        Core.Instance.event.emit(EEvent.EnemyBuffChanged);
    }
    
    addBuff(buff: Buff) {
        this.buffs.push(buff);
        Core.Instance.event.emit(EEvent.EnemyBuffChanged);
    }
    
    update(dt: number) {
        for (let i = this.buffs.length - 1; i >= 0; i--) {
            const buff = this.buffs[i];
            buff.elapsed += dt;
            
            if (buff.elapsed >= buff.duration) {
                this.removeBuffAt(i);
            }
        }
    }
    
    protected removeBuffAt(index: number) {
        this.buffs.splice(index, 1);
        Core.Instance.event.emit(EEvent.EnemyBuffChanged);
    }

    /**
     * 检查是否存在指定类型的Buff
     * @param type 要检查的Buff类型
     * @returns 如果存在该类型的Buff返回true，否则返回false
     */
    hasBuff(type: EBuff): boolean {
        return this.buffs.some(buff => buff.type === type);
    }

    /**
     * 检查是否存在指定类型和来源的Buff
     * @param type 要检查的Buff类型
     * @param playerType 施加Buff的玩家类型
     * @returns 如果存在符合条件的Buff返回true，否则返回false
     */
    hasBuffFromPlayer(type: EBuff, playerType: EPlayerType): boolean {
        return this.buffs.some(buff => buff.type === type && buff.playerType === playerType);
    }

    /**
     * 获取指定类型的所有Buff
     * @param type 要获取的Buff类型
     * @returns 该类型的所有Buff数组
     */
    getBuffsByType(type: EBuff): Buff[] {
        return this.buffs.filter(buff => buff.type === type);
    }

    /**
     * 获取指定类型Buff的数量
     * @param type 要检查的Buff类型
     * @returns 该类型Buff的数量
     */
    getBuffCount(type: EBuff): number {
        return this.buffs.filter(buff => buff.type === type).length;
    }

    /**
     * 检查是否存在持续伤害类型的Buff（如中毒、燃烧等）
     * @returns 如果存在持续伤害Buff返回true，否则返回false
     */
    hasDotBuff(): boolean {
        return this.buffs.some(buff => buff.isDot);
    }

    /**
     * 检查是否存在特定类型的持续伤害Buff
     * @param type 要检查的持续伤害Buff类型
     * @returns 如果存在该类型的持续伤害Buff返回true，否则返回false
     */
    hasSpecificDotBuff(type: EBuff): boolean {
        return this.buffs.some(buff => buff.isDot && buff.type === type);
    }
}


// EnemyBuffManager 继承自 BuffManager，用于处理敌人身上的Buff
export class EnemyBuffManager extends BuffManager {
    private enemy: EnemyManager;
    
    constructor(enemy: EnemyManager) {
        super();
        this.enemy = enemy;
    }
    
    addBuff(buff: Buff) {
        super.addBuff(buff);
        this.applyBuffEffect(buff);
    }
    
    protected removeBuffAt(index: number) {
        const buff = this.buffs[index];
        this.revertBuffEffect(buff);
        super.removeBuffAt(index);
    }
    
    private applyBuffEffect(buff: Buff) {
        switch (buff.type) {
            case EBuff.Slow:
                this.enemy.slow(buff.ap);
                break;
                
            case EBuff.Freeze:
                console.log("addbuff freeze in applyBuffEffect")
                this.enemy.freeze();
                break;
                
            case EBuff.Stun:
                this.enemy.stun();
                break;
                
            case EBuff.Poison:
                this.enemy.addPoisonStack(
                    buff.ap/100 * Core.Instance.players.get(buff.playerType).ap, 
                    buff.duration, 
                    buff.playerType
                );
                break;
                
            case EBuff.Burn:
                this.enemy.burn(
                    buff.ap * Core.Instance.players.get(buff.playerType).ap, 
                    buff.playerType

                );
                break;
            case EBuff.Blind:
                this.enemy.stun();
                break;
                
            case EBuff.KnockBack:
                this.enemy.knockBack();
                break;

            case EBuff.DefenceDown:
                this.enemy.defenceDown(buff.ap);
                break;
                
            case EBuff.AttackDown:
                this.enemy.attackDown(buff.ap);
                break;
                
            case EBuff.Miss:
                this.enemy.miss(buff.ap);
                break;

            case EBuff.Vulnerable:
                this.enemy.isVulnerable = true; // 设置易伤状态
                break;

            case EBuff.Weak:
                this.enemy.weak(buff.ap); // 设置虚弱状态
                break;
            case EBuff.Fear:
                this.enemy.fear(); // 设置虚弱状态
                break;
            case EBuff.Silence:
                this.enemy.silence(); // 设置沉默状态
                break;
            case EBuff.Explosion:
                this.enemy.explosion(); // 设置沉默状态
                break;
            case EBuff.Disarm:
                this.enemy.disarm(); // 设置沉默状态
                break;
            default:
                console.warn(`未知Buff类型: ${buff.type}`);
                break;
        }
    }
    
    private revertBuffEffect(buff: Buff) {
        switch (buff.type) {
            case EBuff.Slow:
                this.enemy.revertSlow();
                break;
                
            case EBuff.Freeze:
                this.enemy.revertFreeze();
                break;
                
            case EBuff.Stun:
                this.enemy.revertStun();
                break;
            case EBuff.Blind:
                this.enemy.revertStun();
                break;
                
            case EBuff.Miss:
                this.enemy.revertMiss();
                break;

            case EBuff.DefenceDown:
                this.enemy.revertDefenceDown();
                break;
                
            case EBuff.AttackDown:
                this.enemy.revertAttackDown();
                break;
            case EBuff.Vulnerable:
                this.enemy.isVulnerable = false; // 取消易伤状态
                break;
            case EBuff.Weak:
                this.enemy.revertWeak(); // 恢复原始攻击力
                break;
            case EBuff.Fear:
                this.enemy.revertFear(); // 恢复原始状态
                break;
            case EBuff.Silence:
                this.enemy.revertSilence(); // 恢复原始状态
                break;
            case EBuff.Explosion:
                this.enemy.revertExplosion(); // 恢复原始状态
                break;
            case EBuff.Disarm:
                this.enemy.revertDisarm(); // 设置沉默状态
                break;
            default:
                // 其他Buff不需要撤销效果
                break;  
        }
    }
}



























export class PlayerBuffManager extends BuffManager {
    private player: PlayerManager;
    private originalValues: Map<EBuff, any> = new Map();
    
    constructor(player: PlayerManager) {
        super();
        this.player = player;
    }
    
    addBuff(buff: Buff) {
        super.addBuff(buff);
        this.applyBuffEffect(buff);
    }
    
    protected removeBuffAt(index: number) {
        const buff = this.buffs[index];
        this.revertBuffEffect(buff);
        super.removeBuffAt(index);
    }
    
    private applyBuffEffect(buff: Buff) {
        switch (buff.type) {
            case EBuff.Attack:
                this.originalValues.set(buff.type, this.player.ap);
                this.player.ap += buff.ap;
                break;
                
            case EBuff.CriticalChance:
                this.originalValues.set(buff.type, this.player.criticalChance);
                this.player.criticalChance += buff.ap;
                break;
                
            case EBuff.AttackSpeed:
                this.originalValues.set(buff.type, this.player.attackSpeed);
                this.player.attackSpeed -= buff.ap;
                break;
                
            case EBuff.CriticalDamage:
                this.originalValues.set(buff.type, this.player.criticalDamage);
                this.player.criticalDamage += buff.ap;
                break;
                
            case EBuff.Shield:
                this.originalValues.set(buff.type, this.player.sheild);
                WallManager.Instance.sheild += buff.ap;
                WallManager.Instance.updateShieldDisplay();
                break;
        }
    }
    
    private revertBuffEffect(buff: Buff) {
        switch (buff.type) {
            case EBuff.Attack:
                this.player.ap = this.originalValues.get(buff.type) || this.player.ap;
                break;
                
            case EBuff.CriticalChance:
                this.player.criticalChance = this.originalValues.get(buff.type) || this.player.criticalChance;
                break;
                
            case EBuff.AttackSpeed:
                this.player.attackSpeed = this.originalValues.get(buff.type) || this.player.attackSpeed;
                break;
                
            case EBuff.CriticalDamage:
                this.player.criticalDamage = this.originalValues.get(buff.type) || this.player.criticalDamage;
                break;
                
            case EBuff.Shield:
                this.player.sheild = this.originalValues.get(buff.type) || this.player.sheild;
                WallManager.Instance.updateShieldDisplay();
                break;
        }
    }
}